package com.suredy.app.porject.ctrl;

import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.suredy.app.porject.constants.ContractOpLogType;
import com.suredy.app.porject.constants.MoneyType;
import com.suredy.app.porject.model.Contract;
import com.suredy.app.porject.model.ContractMoney;
import com.suredy.app.porject.model.ContractOpLog;
import com.suredy.app.porject.model.sp.Money;
import com.suredy.app.porject.service.ContractMoneySrv;
import com.suredy.app.porject.service.ContractOpLogSrv;
import com.suredy.core.ctrl.BaseCtrl;
import com.suredy.core.mvc.model.MessageModel;

/**
 * 资金管理控制器（合同）
 * 
 * @author VIVID.G
 * @since 2015-12-30
 * @version v0.1
 */
@Controller
@RequestMapping("/money")
public class ContractMoneyCtrl extends BaseCtrl {

	@Autowired
	private ContractMoneySrv contractMoneySrv;

	@Autowired
	private ContractOpLogSrv contractOpLogSrv;

	@RequestMapping("/new-form")
	public String newContractBackMoneyForm(boolean payOut, MoneyType type, String contractId, String source, Model model) {
		String view = "app/money/money-new";

		if (type == null || StringUtils.isBlank(contractId))
			return view;

		if (StringUtils.isBlank(source))
			source = null;

		ContractMoney money = new ContractMoney();

		money.setContract(new Contract());
		money.getContract().setId(contractId);
		money.setBackTime(null);
		money.setGaveBack(false);
		money.setInAccount(true);
		money.setInvoice(false);
		money.setName(type.getValue());
		money.setPayOut(payOut);
		money.setRemark(null);
		money.setSource(source);
		money.setTime(null);
		money.setTotal(null);

		model.addAttribute("data", money);

		return view;
	}

	@RequestMapping("/new")
	@ResponseBody
	public Object newContractBackMoney(ContractMoney money) {
		if (money == null)
			return MessageModel.createErrorMessage("无效的资金信息！", null);

		money = this.contractMoneySrv.save(money);

		if (money == null || StringUtils.isBlank(money.getId()))
			return MessageModel.createErrorMessage("无法保存资金信息！", null);

		// 记录主合同操作日志
		ContractOpLog log = this.recordOpLog(money.getContract(), this.getOpLogTypeByMoneyName(money.getName()), this.makeOpLogText(money));
		if (log == null)
			return new MessageModel(false, "记录操作日志出错", null);
		this.contractOpLogSrv.save(log);

		return MessageModel.createSuccessMessage("操作成功", null);
	}

	@RequestMapping("/back")
	@ResponseBody
	public Object backMoney(String moneyId) {
		if (StringUtils.isBlank(moneyId))
			return MessageModel.createErrorMessage("资金信息无效！", null);

		ContractMoney money = this.contractMoneySrv.get(moneyId);

		if (money == null)
			return MessageModel.createErrorMessage("未能找到对应的资金信息！", null);

		if (money.getGaveBack() == null) {
			String tmp;

			if (money.getPayOut()) {
				tmp = "资金信息不可【收回】";
			} else {
				tmp = "资金信息不可【退回】";
			}

			return MessageModel.createErrorMessage(tmp, null);
		}

		money.setGaveBack(true);

		money = this.contractMoneySrv.update(money);

		if (money == null || StringUtils.isBlank(money.getId()))
			return MessageModel.createErrorMessage((money.getPayOut() ? "收回" : "退回") + "资金失败！", null);

		return MessageModel.createSuccessMessage("操作成功", null);
	}

	@RequestMapping("/delete")
	@ResponseBody
	public Object deleteMoney(String moneyId) {
		if (StringUtils.isBlank(moneyId))
			return MessageModel.createErrorMessage("资金信息无效！", null);

		ContractMoney money = this.contractMoneySrv.get(moneyId);

		if (money == null)
			return MessageModel.createErrorMessage("未能找到对应的资金信息！", null);

		money = this.contractMoneySrv.delete(money);

		if (money == null || StringUtils.isBlank(money.getId()))
			return MessageModel.createErrorMessage("删除资金失败！", null);

		return MessageModel.createSuccessMessage("操作成功", null);
	}

	private String makeOpLogText(Money money) {
		if (money == null)
			return null;

		String text = money.getName() + "：" + this.numberFormat(money.getTotal()) + "（" + this.datetimeFormat(money.getTime(), "yyyy-MM-dd") + "）";

		return text;
	}

	/**
	 * 新建操作日志
	 * 
	 * @param op
	 * @param remark
	 * @return
	 */
	private ContractOpLog newOpLog(ContractOpLogType op, String remark) {
		if (op == null)
			return null;

		ContractOpLog log = new ContractOpLog();

		log.setTime(new Date());
		log.setOp(op);
		log.setOper(this.getUser().getName());
		log.setRemark(remark);

		return log;
	}

	/**
	 * 记录操作日志
	 * 
	 * @param c
	 * @param op
	 * @param remark
	 */
	private ContractOpLog recordOpLog(Contract c, ContractOpLogType op, String remark) {
		if (c == null)
			return null;

		ContractOpLog log = this.newOpLog(op, remark);

		if (log == null)
			return null;

		if (c.getOpLog() == null)
			c.setOpLog(new ArrayList<ContractOpLog>());

		log.setContract(c);

		c.getOpLog().add(log);

		return log;
	}

	private String numberFormat(double number) {
		NumberFormat nf = new DecimalFormat("￥#,###.00");

		return nf.format(number);
	}

	private String datetimeFormat(Date d, String pattern) {
		if (d == null)
			return "";

		SimpleDateFormat sdf = new SimpleDateFormat(pattern);

		return sdf.format(d);
	}

	public ContractOpLogType getOpLogTypeByMoneyName(String name) {
		MoneyType mt = MoneyType.getByValue(name);

		if (mt == null)
			return ContractOpLogType.UNKNOW;

		switch (mt) {
			case C_ZB:
				return ContractOpLogType.CONTRACT_ZB_MONEY;
			case C_YF:
				return ContractOpLogType.CONTRACT_YF_MONEY;
			case C_LY:
				return ContractOpLogType.CONTRACT_LY_MONEY;
			case C_GZ:
				return ContractOpLogType.CONTRACT_GZ_MONEY;
			case C_YFK:
				return ContractOpLogType.CONTRACT_YFK_MONEY;
		}

		return ContractOpLogType.UNKNOW;
	}

}
